# -*- coding: utf-8 -*-
# @Time    : 2016/9/20
from mathsolver.functions.hanshu.helper import check_func, check_inter, MathematicaOptimize, BaseOptimize
from mathsolver.functions.base import BaseNumber, BaseVariable, BaseFunction, BaseValue
from mathsolver.functions.daoshu.jizhi import HanShuJiZhi, HanShuJiDaZhi, HanShuJiXiaoZhi


class HanShuZuiXiaoZhi(BaseFunction):
    """"求函数最小值"""

    def solver(self, *args):
        func = args[0]
        qiujizhi = HanShuJiXiaoZhi().solver(func)

        if not qiujizhi.jixiaozhidian:
            jizhi = None
            qiujizhi.steps.append(["函数最小值不存在", ""])
        else:
            jizhi = min([item[1] for item in qiujizhi.jixiaozhidian])
            qiujizhi.steps.append(["所以函数的最小值为 {}".format(jizhi), ""])

        qiujizhi.output = [BaseNumber(jizhi)]
        qiujizhi.label = {"利用导数求函数的最值", }
        return qiujizhi


class HanShuZuiDaZhi(BaseFunction):
    """"求函数最大值"""

    def solver(self, *args):
        func = args[0]
        qiujizhi = HanShuJiDaZhi().solver(func)

        if not qiujizhi.jidazhidian:
            jizhi = None
            qiujizhi.steps.append(["函数最大值不存在", ""])
        else:
            jizhi = max([item[1] for item in qiujizhi.jidazhidian])
            qiujizhi.steps.append(["所以函数的最大值为 {}".format(jizhi), ""])

        qiujizhi.output = [BaseNumber(jizhi)]
        qiujizhi.label = {"利用导数求函数的最值", }
        return qiujizhi


class HanShuZuiZhi(BaseFunction):
    """"求函数最值"""

    def solver(self, *args):
        func = args[0]
        qiujizhi = HanShuJiZhi().solver(func)

        if not qiujizhi.jixiaozhidian:
            jixiaozhi = None
            qiujizhi.steps.append(["", "函数最小值不存在"])
        else:
            jixiaozhi = min([item[1] for item in qiujizhi.jixiaozhidian])
            qiujizhi.steps.append(["", "所以函数的最小值为 {}".format(jixiaozhi)])

        if not qiujizhi.jidazhidian:
            jidazhi = None
            qiujizhi.steps.append(["", "函数最大值不存在"])
        else:
            jidazhi = max([item[1] for item in qiujizhi.jidazhidian])
            qiujizhi.steps.append(["", "所以函数的最大值为 {}".format(jidazhi)])

        qiujizhi.output = [BaseValue([jixiaozhi, jidazhi])]
        qiujizhi.label = {"利用导数求函数的最值", }
        return qiujizhi


class MathMaxSolver(BaseFunction):
    """BUG: CANNOT SOLVE - Maximize[{2^x + m, 0 <= x <= 2}, x, Reals]"""
    min_max = "Maximize"
    symb = "最大值"
    symb2 = "上限"

    def solver(self, *args):
        func = check_func(args[0])

        if len(args) > 1:
            interval = check_inter(args[1])
        else:
            interval = None

        math_solver = MathematicaOptimize().solver(
            BaseOptimize(func.expression, self.min_max, interval), BaseVariable([func.var]))

        solve_y, solve_x, reacheable = math_solver.output

        if reacheable:
            self.steps.append(["", "当 %s 时，函数 %s 的%s为 %s" %
                               (solve_x.printing(), func.printing(), self.symb, solve_y.printing())])
        else:
            self.steps.append(["", "函数的%s不存在，当 %s 时，函数 %s 的%s为 %s" %
                               (self.symb, solve_x.printing(), func.printing(), self.symb2, solve_y.printing())])

        self.output = math_solver.output
        self.label.add("求函数的最值")
        return self


class MathMinSolver(MathMaxSolver):
    min_max = "Minimize"
    symb = "最小值"
    symb2 = "下限"


if __name__ == "__main__":
    pass
